/******************************************************************************
  * @file    PT32X005_adc.c
  * @author  应用开发团队
  * @version V1.1.0
  * @date    2020/1/27
  * @brief   This file provides firmware functions to manage the following
  *          functionalities of the ADC peripheral:
  *           + Initialization and Configuration
  *           + Interrupts and flags management
  *
  ******************************************************************************
  * @attention
  *
  *
  *****************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "PT32X005_adc.h"


/** @defgroup ADC
  * @brief ADC driver modules
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define INICFR_CLEAR_MASK           ((u32)0x00003B0F)
#define CALIBRATION_TIMEOUT         ((u32)0x00000FFF)

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/


/**
  * @brief  Deinitializes the ADCx peripheral registers to their default reset values.
  * @param  ADCx: where x can be 1 to select the ADC peripheral.
  * @retval None
  */
void ADC_DeInit(ADC_TypeDef* ADCx)
{
	/* Check the parameters */
	assert_param(IS_ADC_ALL_PERIPH(ADCx));
	ADCx->CR=0;
	ADCx->SAMPLE=0;
}

/**
  * @brief  Initializes the ADCx peripheral according to the specified parameters
  *         in the ADC_InitStruct.
  * @param  ADCx: where x can be 1 to select the ADC peripheral.
  * @param  ADC_InitStruct: pointer to an ADC_InitTypeDef structure that contains
  *         the configuration information for the specified ADC peripheral.
  * @retval None
  */
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct)
{
	u32 tmpreg = 0;
	/* Check the parameters */
	assert_param(IS_ADC_ALL_PERIPH(ADCx));
	assert_param(IS_ADC_PSC_SEL(ADC_InitStruct->ADC_PSC_SEL));
	assert_param(IS_ADC_MODE_SEL(ADC_InitStruct->ADC_MODE_SEL));
	assert_param(IS_ADC_ALIGN_SEL(ADC_InitStruct->ADC_ALIGN_SEL));
	assert_param(IS_ADC_BGS_SEL(ADC_InitStruct->ADC_BGS_SEL));
	assert_param(IS_ADC_TIMS_SEL(ADC_InitStruct->ADC_TIMS_SEL));
	/* Get the ADCx CFGR value */
	tmpreg = ADCx->CR;
	/* Clear SCANDIR, RES[1:0], ALIGN, EXTSEL[2:0], EXTEN[1:0] and CONT bits */
	tmpreg &= INICFR_CLEAR_MASK;
	/*---------------------------- ADCx CFGR Configuration ---------------------*/
	/* Set MODE bit according to ADC_MODE_SEL value */
	/* Set EXTSEL[5:2] bits according to ADC_TIMS_SEL value */
	/* Set DISH bit according to ADC_OffsetCalibration value */
	/* Set ALIGN bit according to ADC_ALIGN_SEL value */
	tmpreg  |= (ADC_InitStruct->ADC_MODE_SEL) |
	           	( ADC_InitStruct->ADC_TIMS_SEL ) |
	           	(ADC_InitStruct->ADC_ALIGN_SEL)|
			(ADC_InitStruct->ADC_BGS_SEL)|
			(ADC_InitStruct->ADC_PSC_SEL);
	/* Write to ADCx CFGR */
	ADCx->CR = tmpreg;
}

/**
  * @brief  Fills each ADC_InitStruct member with its default value.
  * @param  ADC_InitStruct: pointer to an ADC_InitTypeDef structure which will
  *         be initialized.
  * @retval None
  */
void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct)
{
	/* Reset ADC init structure parameters values */
	ADC_InitStruct->ADC_PSC_SEL=ADC_CR_PSC_16;
	/* Initialize the ADC_MODE_SEL member */
	ADC_InitStruct->ADC_MODE_SEL = ADC_CR_MODE_Single;
	/* Initialize the ADC_ALIGN_SEL member */
	ADC_InitStruct->ADC_ALIGN_SEL = ADC_ALIGN_Right;
	ADC_InitStruct->ADC_BGS_SEL=ADC_BGS_BG1v2;
	/* Initialize the ADC_TIMS_SEL member */
	ADC_InitStruct->ADC_TIMS_SEL = ADC_CR_TIMS_None;
}

/**
  * @brief  Enables or disables the specified ADC peripheral.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @param  NewState: new state of the ADCx peripheral.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState)
{
	/* Check the parameters */
	assert_param(IS_ADC_ALL_PERIPH(ADCx));
	assert_param(IS_FUNCTIONAL_STATE(NewState));
	if (NewState != DISABLE)
	{
		/* Set the ADEN bit to Enable the ADC peripheral */
		ADCx->CR |= ((u32)0x00000020);
	}
	else
	{
		/* Reset the ADEN to Disable the ADC peripheral */
		ADCx->CR &=((u32)~0x00000020);
	}
}


/**
  * @brief  Set ADC sample times the specified ADC peripheral.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @param  SAM_Time: sample time value (3~255).
  * @retval None
  */
void ADC_SetSampleTime(ADC_TypeDef* ADCx, u32 SAM_Time)
{
	/* Check the parameters */
	assert_param(IS_ADC_ALL_PERIPH(ADCx));
	assert_param(IS_ADC_SAM_VAL(SAM_Time));
	ADCx->SAMPLE = SAM_Time;
}


/**
  * @brief  Configures for the selected ADC and its channel
  * @param  ADCx: where x can be 1 to select the ADC peripheral.
  * @param  ADC_Channel: the ADC channel to configure.
  *          This parameter can be any combination of the following values:
  *            @arg ADC_CR_CHS_0: ADC Channel0 selected
  *            @arg ADC_CR_CHS_1: ADC Channel1 selected
  *            @arg ADC_CR_CHS_2: ADC Channel2 selected
  *            @arg ADC_CR_CHS_3: ADC Channel3 selected
  *            @arg ADC_CR_CHS_4: ADC Channel4 selected
  *            @arg ADC_CR_CHS_5: ADC Channel5 selected
  *            @arg ADC_CR_CHS_6: ADC Channel6 selected
  *            @arg ADC_CR_CHS_7: ADC Channel7 selected
  *            @arg ADC_CR_CHS_8: ADC Channel8 selected
  *            @arg ADC_CR_CHS_9: ADC Channel9 selected
  *            @arg ADC_CR_CHS_10: ADC Channel10 selected
  * @retval None
  */
void ADC_ChannelConfig(ADC_TypeDef* ADCx, u32 ADC_Channel)
{
	/* Check the parameters */
	assert_param(IS_ADC_ALL_PERIPH(ADCx));
	assert_param(IS_ADC_CHS_SEL(ADC_Channel));
	/* Clear the ADC Channel Selection bits */
	ADCx->CR &= (u32)~0x0000001F;
	/* Configure the ADC Channel */
	ADCx->CR |= (u32)ADC_Channel;
}

/**
  * @brief  Start Conversion for the selected ADC channels.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @retval None
  */
void ADC_ConversionConfig(ADC_TypeDef* ADCx,FunctionalState NewState)
{
	/* Check the parameters */
	assert_param(IS_ADC_ALL_PERIPH(ADCx));

	assert_param(IS_FUNCTIONAL_STATE(NewState));
	if (NewState != DISABLE)
	{
		ADCx->CR |= (u32)0x00000080;
	}
	else
	{
		// None
	}
}

/**
  * @brief  Returns the last ADCx conversion result data for ADC channel.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @retval The Data conversion value.
  */
u16 ADC_GetConversionValue(ADC_TypeDef* ADCx)
{
	/* Check the parameters */
	assert_param(IS_ADC_ALL_PERIPH(ADCx));
	/* Return the selected ADC conversion value */
	return (u16) ADCx->DR;
}

/**
  * @brief  Checks whether the specified ADC flag is set or not.
  * @param  ADCx: where x can be 1 to select the ADC1 peripheral.
  * @param  ADC_FLAG: specifies the flag to check.
  *          This parameter can be one of the following values:
  *            @arg ADC_FLAG_EOC: End of conversion flag
  *            @arg ADC_FLAG_ADRDY: ADC Ready flag
  * @retval The new state of ADC_FLAG (SET or RESET).
  */
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, u32 ADC_FLAG)
{
	FlagStatus bitstatus = RESET;
	/* Check the parameters */
	assert_param(IS_ADC_ALL_PERIPH(ADCx));
	assert_param(IS_ADC_GET_FLAG(ADC_FLAG));
	/* Check the status of the specified ADC flag */
	if ((ADCx->SR & ADC_FLAG) != (u32)RESET)
	{
		/* ADC_FLAG is set */
		bitstatus = SET;
	}
	else
	{
		/* ADC_FLAG is reset */
		bitstatus = RESET;
	}
	/* Return the ADC_FLAG status */
	return  bitstatus;
}




/**
  * @}
  */
